extends Node2D
class_name BattleAnimScene

@onready var nameCareerLeft: Label = $UI/InfoLeft/NameCareer
@onready var levelLeft: Label = $UI/InfoLeft/Level
@onready var nameCareerRight: Label = $UI/InfoRight/NameCareer
@onready var levelRight: Label = $UI/InfoRight/Level
@onready var actorLeft: BattleActor = $LeftActorPos/BattleActor
@onready var actorRight: BattleActor = $RightActorPos/BattleActor
@onready var hpBarLeft: BattleAnimHpBar = $UI/InfoLeft/BattleAnimHpBar
@onready var hpBarRight: BattleAnimHpBar = $UI/InfoRight/BattleAnimHpBar2
@onready var hitBarLeft: Control = $UI/InfoLeft/HITBarLeft
@onready var atcBarLeft: Control = $UI/InfoLeft/ATCBarLeft
@onready var defBarLeft: Control = $UI/InfoLeft/DEFBarLeft
@onready var hitBarRight: Control = $UI/InfoRight/HITBarRight
@onready var atcBarRight: Control = $UI/InfoRight/ATCBarRight
@onready var defBarRight: Control = $UI/InfoRight/DEFBarRight
@onready var bottomBgLeft01: ColorRect = $UI/InfoLeft/BottomBg
@onready var bottomBgLeft02: ColorRect = $UI/InfoLeft/BottomBg2
@onready var bottomBgRight01: ColorRect = $UI/InfoRight/BottomBg
@onready var bottomBgRight02: ColorRect = $UI/InfoRight/BottomBg2
@onready var sequence: Sequence = $Sequence
@onready var summaryInfo: NinePatchRect = $UI/SummaryInfo
@onready var actionInfo: NinePatchRect = $UI/ActionInfo
@onready var expInfo: NinePatchRect = $UI/ExpInfo
@onready var actionInfoLabel: Label = $UI/ActionInfo/Label
@onready var sequenceWaitTimer: Timer = $Timer/SequenceWaitTimer
@onready var expBar: BattleAnimAttrBar = $UI/ExpInfo/ExpBar
@onready var animationPlayer: AnimationPlayer = $AnimationPlayer

var redColorHex = "ff0000"
var blueColorHex = "1a29ff"

var battleAnimData
var attackDataLeft
var attackDataRight
var actorLeftData
var actorRightData
var unitLeft:BattleFieldUnit
var unitRight:BattleFieldUnit
var terrainLeft
var terrainRight

var battleField:BattleField

#sequence
var onTakeEffect = false
var waitTimeStarted = false

var g = GlobalUtils


func _ready() -> void:
	actionInfo.hide()
	summaryInfo.hide()
	expInfo.hide()
	expBar.setBlue()
	hide()
	

func init(_battleAnimData, _battleField):
	battleAnimData = _battleAnimData
	attackDataLeft = battleAnimData.attackDataLeft
	attackDataRight = battleAnimData.attackDataRight
	battleField = _battleField
	
	initActor()
	initActorSignals()
	initNameCareerLv()
	updateBottomBgColor()
	updateActorHpView()
	updateActorAttrView()
	
	startAnim()
	

func initActor():
	unitLeft = battleAnimData.unitLeft
	unitRight = battleAnimData.unitRight
	
	terrainLeft = battleField.getTerrainInfoByCell(unitLeft.getCell())
	terrainRight = battleField.getTerrainInfoByCell(unitRight.getCell())
	
	actorLeftData = unitLeft.charData
	actorRightData = unitRight.charData
	
	actorLeft.init(actorLeftData)
	actorRight.init(actorRightData)
	

func initNameCareerLv():
	nameCareerLeft.text = actorLeftData.charConfig.name + "\n" + actorLeftData.careerConfig.name
	levelLeft.text = "LV" + str(actorLeftData.level)
	
	nameCareerRight.text = actorRightData.charConfig.name + "\n" + actorRightData.careerConfig.name
	levelRight.text = "LV" + str(actorRightData.level)
	

func initActorSignals():
	actorLeft.sigTakeEffect.connect(actorLeftTakeEffectHandler)
	actorRight.sigTakeEffect.connect(actorRightTakeEffectHandler)
	actorLeft.sigPauseAnim.connect(actorLeftPauseAnimHandler)
	actorRight.sigPauseAnim.connect(actorRightPauseAnimHandler)
	
	
func updateBottomBgColor():
	bottomBgLeft01.color = redColorHex
	bottomBgLeft02.color = redColorHex
	bottomBgRight01.color = blueColorHex
	bottomBgRight02.color = blueColorHex
	
	
func updateActorHpView():
	hpBarLeft.setRed()
	hpBarLeft.setMaxHp(actorLeftData.hp)
	hpBarLeft.setHp(actorLeftData.battleHp)
	hpBarRight.setBlue()
	hpBarRight.setMaxHp(actorRightData.hp)
	hpBarRight.setHp(actorRightData.battleHp)
	
	
func updateActorAttrView():
	hitBarLeft.setRed()
	atcBarLeft.setRed()
	defBarLeft.setRed()
	hitBarRight.setBlue()
	atcBarRight.setBlue()
	defBarRight.setBlue()
	
	hitBarLeft.setValue(attackDataLeft["hit"])
	atcBarLeft.setValue(actorLeftData.attack)
	defBarLeft.setValue(actorLeftData.defense)
	
	hitBarRight.setValue(attackDataRight["hit"])
	atcBarRight.setValue(actorRightData.attack)
	defBarRight.setValue(actorRightData.defense)
	
	
func handleSequenceCommandAttack(params, sequences):
	# attack,right,first,normal,0 
	var executor = params[1]
	var round = params[2]
	var attackAnimName = params[3]
	var damage = params[4]
	
	var actorAttackNode
	var actionMsg = ""
	var actorLostHpNode
	var actor 
	var target
	
	if executor == "left":
		actorAttackNode = g.sn(actorAttack, [actorLeft, attackAnimName])
		actionMsg += actorLeft.data.charConfig.name
		actorLostHpNode = g.sn(actorLostHp, [hpBarRight, int(damage)])
		actor = actorLeft
		target = actorRight
	if executor == "right":
		actorAttackNode = g.sn(actorAttack, [actorRight, attackAnimName])
		actionMsg += actorRight.data.charConfig.name
		actorLostHpNode = g.sn(actorLostHp, [hpBarLeft, int(damage)])
		actor = actorRight
		target = actorLeft
	
	if round == "first": actionMsg += "的攻击"
	if round == "fanji": actionMsg += "的反击"
	if round == "zhuiji": actionMsg += "的追击"
	
	var actionMsgNode = g.sn(showActionMsg, actionMsg)
	var damageMsgNode 
	var hitEffectNode = g.snEmpty()
	if int(damage) <= 0:
		damageMsgNode = g.sn(showActionMsg, target.data.charConfig.name + "快速避开了")
	elif attackAnimName == "critical":
		damageMsgNode = g.sn(showActionMsg, "致命一击，造成" + damage + "点伤害")
		hitEffectNode = g.sn(actorHitEffect, target)
	else:
		damageMsgNode = g.sn(showActionMsg, damage + "点伤害")
		hitEffectNode = g.sn(actorHitEffect, target)
		
	var checkAndResumeActorAnimNode = g.sn(checkAndResumeActorAnim, actor)
	var hideActionNode = g.sn(hideActionMsg)
	var waitTillTakeEffectNode = g.sn(waitTillTakeEffect)
	var waitNode = g.sn(wait)
	var waitTillActorStopAnimNode = g.sn(waitTillActorStopAnim, actor)
	
	sequences.append_array([
		[actorAttackNode, actionMsgNode],
		waitTillTakeEffectNode,
		[damageMsgNode, actorLostHpNode, hitEffectNode],
		waitNode,
		[checkAndResumeActorAnimNode, hideActionNode],
		waitTillActorStopAnimNode
	])
		

func handleSequenceCommandSummary(params, sequences:Array):
	var showSummaryInfoNode = g.sn(showSummaryInfo)
	
	sequences.append_array([
		showSummaryInfoNode
	])
	

func handleSequenceCommandExp(params, sequences:Array):
	var showExpInfoNode = g.sn(showExpInfo)
	
	sequences.append_array([
		showExpInfoNode
	])
	

func handleSequenceCommandWait(params, sequences:Array):
	var waitNode = g.sn(wait)
	
	sequences.append_array([
		waitNode
	])
	

func handleSequenceCommandCutScene(params, sequences:Array):
	var cutSceneNode = g.sn(cutScene, params[1])
	var waitTillCutSceneDoneNode = g.sn(waitTillCutSceneDone)
	
	sequences.append_array([
		cutSceneNode,
		waitTillCutSceneDoneNode
	])
	
	
func startAnim():
	var sequences = []
	for sequenceStr:String in battleAnimData.sequences:
		var params = sequenceStr.split(',')
		var commandStr = params[0]
		if commandStr == Consts.ANIM_COMMAND_CUTSCENE:
			handleSequenceCommandCutScene(params, sequences)
		if commandStr == Consts.ANIM_COMMAND_ATTACK:
			handleSequenceCommandAttack(params, sequences)
		if commandStr == Consts.ANIM_COMMAND_SUMMARY:
			handleSequenceCommandSummary(params, sequences)
		if commandStr == Consts.ANIM_COMMAND_EXP:
			handleSequenceCommandExp(params, sequences)
		if commandStr == Consts.ANIM_COMMAND_WAIT:
			handleSequenceCommandWait(params, sequences)
	
	sequence.setNodes(sequences)
	sequence.play()
	

func actorLeftTakeEffectHandler():
	onTakeEffect = true
	

func actorRightTakeEffectHandler():
	onTakeEffect = true


func actorLeftPauseAnimHandler():
	actorLeft.pauseAnim()
	

func actorRightPauseAnimHandler():
	actorRight.pauseAnim()


# sequences
func actorAttack(params):
	var actor = params[0]
	var animName = params[1]
	actor.playAnim(animName)
	return true
	

func showActionMsg(msg):
	actionInfoLabel.text = msg
	actionInfo.show()
	return true
	

func showDamageMsg():
	actionInfoLabel.text = "8点伤害"
	actionInfo.show()
	return true
	

func hideActionMsg():
	actionInfo.hide()
	return true


func actorLostHp(params):
	var hpBar = params[0]
	var hp = params[1]
	hpBar.setHp(hpBar.getHp() - hp) 
	return true
	

func wait():
	if not waitTimeStarted:
		sequenceWaitTimer.start()
		waitTimeStarted = true
	if waitTimeStarted and sequenceWaitTimer.time_left <= 0:
		waitTimeStarted = false
		return true
	return false
	
	
func waitTillTakeEffect():
	if onTakeEffect:
		onTakeEffect = false
		return true
	return false
	
	
func waitTillActorStopAnim(actor):
	if not actor.isAnimPlaying():
		return true
	return false
	

func checkAndResumeActorAnim(actor):
	if actor.isAnimPaused():
		actor.resumeAnim()
	return true


func showSummaryInfo():
	summaryInfo.show()
	return true
	
	
func showExpInfo():
	expInfo.show()
	expBar.setValue(20)
	expBar.grow2Value(70)
	return true
	

func actorHitEffect(actor):
	if actor == actorLeft:
		animationPlayer.play("HitLeft")
	else:
		animationPlayer.play("HitRight")
	return true
		
	
func cutScene(dir):
	if dir == "left":
		animationPlayer.play("EnterSceneLeft")
	if dir == "right":
		animationPlayer.play("EnterSceneRight")
	return true


func waitTillCutSceneDone():
	if not animationPlayer.is_playing(): 
		return true
	return false
	
	
